package com.kl.drs.util;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.net.SocketException;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.commons.net.ftp.FTPClient;
import org.apache.commons.net.ftp.FTPFile;
import org.apache.commons.net.ftp.FTPReply;

import com.kl.drs.bean.bo.FtpBO;


/**
 * FTP工具类
 * @author WYN
 *
 */
public class FtpUtil {
	 private final static Log logger = LogFactory.getLog(FtpUtil.class);  
	 private static FTPClient ftp;
	    /** 
	     * 获取FTPClient对象 
	     * 
	     * @param ftpHost 
	     *            FTP主机服务器 
	     * @param ftpPassword 
	     *            FTP 登录密码 
	     * @param ftpUserName 
	     *            FTP登录用户名 
	     * @param ftpPort 
	     *            FTP端口 默认为21 
	     * @return 
	     */  
	    public static FTPClient getFTPClient(String ftpHost, String ftpUserName,  
	            String ftpPassword, int ftpPort) {  
	        FTPClient ftpClient = new FTPClient();  
	        try {  
	            ftpClient = new FTPClient();  
	            ftpClient.connect(ftpHost, ftpPort);// 连接FTP服务器  
	            ftpClient.login(ftpUserName, ftpPassword);// 登陆FTP服务器  
	            if (!FTPReply.isPositiveCompletion(ftpClient.getReplyCode())) {  
	                logger.info("未连接到FTP，用户名或密码错误。");  
	                ftpClient.disconnect();  
	            } else {  
	                logger.info("FTP连接成功。");  
	            }  
	        } catch (SocketException e) {  
	            e.printStackTrace();  
	            logger.info("FTP的IP地址可能错误，请正确配置。");  
	        } catch (IOException e) {  
	            e.printStackTrace();  
	            logger.info("FTP的端口错误,请正确配置。");  
	        }  
	        return ftpClient;  
	    }  
	  
	    /* 
	     * 从FTP服务器下载文件 
	     *  
	     * @param ftpHost FTP IP地址 
	     *  
	     * @param ftpUserName FTP 用户名 
	     *  
	     * @param ftpPassword FTP用户名密码 
	     *  
	     * @param ftpPort FTP端口 
	     *  
	     * @param ftpPath FTP服务器中文件所在路径 格式： ftptest/aa 
	     *  
	     * @param localPath 下载到本地的位置 格式：H:/download 
	     *  
	     * @param fileName 文件名称 
	     */  
	    public static void downloadFtpFile(String ftpHost, String ftpUserName,  
	            String ftpPassword, int ftpPort, String ftpPath, String localPath,  
	            String fileName) {  
	  
	        FTPClient ftpClient = null;  
	  
	        try {  
	            ftpClient = getFTPClient(ftpHost, ftpUserName, ftpPassword, ftpPort);  
	            ftpClient.setControlEncoding("UTF-8"); // 中文支持  
	            ftpClient.setFileType(FTPClient.BINARY_FILE_TYPE);  
	            ftpClient.enterLocalPassiveMode();  
	            ftpClient.changeWorkingDirectory(ftpPath);  
	            File localFile = new File(localPath + File.separatorChar + fileName);  
	            /* 判断目录是否存在,不存在的话创建(父目录) */
	            if(!localFile.getParentFile().exists()){
	            	localFile.getParentFile().mkdirs();
	            }
	            OutputStream os = new FileOutputStream(localFile);  
	            ftpClient.retrieveFile(fileName, os);  
	            os.close();  
	            ftpClient.logout();  
	  
	        } catch (FileNotFoundException e) {  
	            logger.error("没有找到" + ftpPath + "文件");  
	            e.printStackTrace();  
	        } catch (SocketException e) {  
	            logger.error("连接FTP失败.");  
	            e.printStackTrace();  
	        } catch (IOException e) {  
	            e.printStackTrace();  
	            logger.error("文件读取错误。");  
	            e.printStackTrace();  
	        }  
	  
	    }  
	    
	    /**
	     * 获取ftp连接
	     * @param f
	     * @return
	     * @throws Exception
	     */
	    public static boolean connectFtp(FtpBO f) throws Exception{
	        ftp=new FTPClient();
	        boolean flag=false;
	        int reply;
	        if (f.getPort()==null) {
	            ftp.connect(f.getIpAddr(),21);
	        }else{
	            ftp.connect(f.getIpAddr(),f.getPort());
	        }
	        ftp.login(f.getUserName(), f.getPwd());
	        ftp.setFileType(FTPClient.BINARY_FILE_TYPE);
	        reply = ftp.getReplyCode();      
	        if (!FTPReply.isPositiveCompletion(reply)) {      
	              ftp.disconnect();      
	              return flag;      
	        }      
	        ftp.changeWorkingDirectory(f.getPath());      
	        flag = true;      
	        return flag;
	    }
	    
	    /**
	     * 关闭ftp连接
	     */
	    public static void closeFtp(){
	        if (ftp!=null && ftp.isConnected()) {
	            try {
	                ftp.logout();
	                ftp.disconnect();
	            } catch (IOException e) {
	                e.printStackTrace();
	            }
	        }
	    }
	    
	    /**
	     * ftp上传文件
	     * @param f
	     * @throws Exception
	     */
	    public static void upload(File f) throws Exception{
	        if (f.isDirectory()) {
	            ftp.makeDirectory(f.getName());
	            ftp.changeWorkingDirectory(f.getName());
	            String[] files=f.list();
	            for(String fstr : files){
	                File file1=new File(f.getPath()+"/"+fstr);
	                if (file1.isDirectory()) {
	                    upload(file1);
	                    ftp.changeToParentDirectory();
	                }else{
	                    File file2=new File(f.getPath()+"/"+fstr);
	                    FileInputStream input=new FileInputStream(file2);
	                    ftp.storeFile(file2.getName(),input);
	                    input.close();
	                }
	            }
	        }else{
	            File file2=new File(f.getPath());
	            FileInputStream input=new FileInputStream(file2);
	            ftp.storeFile(file2.getName(),input);
	            input.close();
	        }
	    }
	    
	    /**
	     * 下载链接配置
	     * @param f
	     * @param localBaseDir 本地目录
	     * @param remoteBaseDir 远程目录
	     * @throws Exception
	     */
	    public static void startDownloadFile(FtpBO f,String localBaseDir,String remoteBaseDir ) throws Exception{
	        if (FtpUtil.connectFtp(f)) {
	            
	            try { 
	                FTPFile[] files = null; 
	                boolean changedir = ftp.changeWorkingDirectory(remoteBaseDir); 
	                if (changedir) { 
	                    ftp.setControlEncoding("GBK"); 
	                    files = ftp.listFiles(); 
	                    for (int i = 0; i < files.length; i++) { 
	                        try{ 
	                            downloadFile(files[i], localBaseDir, remoteBaseDir); 
	                        }catch(Exception e){ 
	                            logger.error(e); 
	                            logger.error("<"+files[i].getName()+">下载失败"); 
	                        } 
	                    } 
	                } 
	            } catch (Exception e) { 
	                logger.error(e); 
	                logger.error("下载过程中出现异常"); 
	            } 
	        }else{
	            logger.error("链接失败！");
	        }
	        
	    }
	    
	    
	    /** 
	     * 
	     * 下载FTP文件 
	     * 当你需要下载FTP文件的时候，调用此方法 
	     * 根据<b>获取的文件名，本地地址，远程地址</b>进行下载 
	     * 
	     * @param ftpFile 
	     * @param relativeLocalPath 
	     * @param relativeRemotePath 
	     */ 
	    private  static void downloadFile(FTPFile ftpFile, String relativeLocalPath,String relativeRemotePath) { 
	        if (ftpFile.isFile()) {
	            if (ftpFile.getName().indexOf("?") == -1) { 
	                OutputStream outputStream = null; 
	                try { 
	                    File locaFile= new File(relativeLocalPath+ ftpFile.getName()); 
	                    //判断文件是否存在，存在则返回 
	                    if(!locaFile.getParentFile().exists()){
	                    	locaFile.getParentFile().mkdirs();
	                    }
	                    	
	                    	outputStream = new FileOutputStream(relativeLocalPath+ ftpFile.getName()); 
	                        ftp.retrieveFile(ftpFile.getName(), outputStream); 
	                        outputStream.flush(); 
	                        outputStream.close(); 
	                    
	                } catch (Exception e) { 
	                    logger.error(e);
	                } finally { 
	                    try { 
	                        if (outputStream != null){ 
	                            outputStream.close(); 
	                        }
	                    } catch (IOException e) { 
	                       logger.error("输出文件流异常"); 
	                    } 
	                } 
	            } 
	        } else { 
	            String newlocalRelatePath = relativeLocalPath + ftpFile.getName(); 
	            String newRemote = new String(relativeRemotePath+ ftpFile.getName().toString()); 
	            File fl = new File(newlocalRelatePath); 
	            if (!fl.exists()) { 
	                fl.mkdirs(); 
	            } 
	            try { 
	                newlocalRelatePath = newlocalRelatePath + '/'; 
	                newRemote = newRemote + "/"; 
	                String currentWorkDir = ftpFile.getName().toString(); 
	                boolean changedir = ftp.changeWorkingDirectory(currentWorkDir); 
	                if (changedir) { 
	                    FTPFile[] files = null; 
	                    files = ftp.listFiles(); 
	                    for (int i = 0; i < files.length; i++) { 
	                        downloadFile(files[i], newlocalRelatePath, newRemote); 
	                    } 
	                } 
	                if (changedir){
	                    ftp.changeToParentDirectory(); 
	                } 
	            } catch (Exception e) { 
	                logger.error(e);
	            } 
	        } 
	    } public static void main(String[] args) throws Exception {
	    	FtpBO f=new FtpBO();
            f.setIpAddr("192.168.0.85");
            f.setUserName("icbc");
            f.setPwd("evhAB6#5");
            f.setPort(21);
           
            FtpUtil.startDownloadFile(new FtpBO("192.168.0.85",21,"icbc","evhAB6#5",null),"e:/ww/","/home/klapp/ftp/CCB/");
            System.out.println("ok");
		}
}
